package com.cn.icss.service.impl;

import com.cn.icss.service.IStreamCallBackService;
import com.cn.icss.utils.StreamEncryUtils;
import com.cn.icss.vo.CallBackRequestData;
import com.cn.icss.vo.StreamInfo;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 * @中软华腾软件系统有限公司,未经授权不得擅自传播
 * @类描述: 回调业务处理类
 * @类名称:StreamCallBackServiceImpl
 * @作者: Administrator
 * @编辑时间: 2020/04/20 16:57
 * @版本: 1.0
 */
public class StreamCallBackServiceImpl implements IStreamCallBackService {
    Logger logger = Logger.getLogger(StreamCallBackServiceImpl.class);
    // redis
    Cache userCache = Redis.use("liveStream");

    private StreamInfo streamInfoDAO = new StreamInfo().dao();

    /**
    *@中软华腾软件系统有限公司,未经授权不得擅自传播
    *@方法描述: 验证用户是否是否是系统登录的用户
    *@方法参数描述:
    ** @param callBackRequestData
    *@作者: 蒋正午
    *@编辑时间: 2020/04/22  12:17
    *@返回值描述: boolean
    */
    @Override
    public boolean authticateUserStream(CallBackRequestData callBackRequestData) {

        boolean flag = true;
        // 判断tcurl中的参数rtmp://192.168.117.20:1935/2001/1001?tokenSecret=3d42315f98fc00760fa554567b0c1eae&token=6666&streamId=123456/123456 只能这么传，如果流放前面我拿不到后面参数
//        String tcUrl = callBackRequestData.getTcUrl();
        // 应该是判断参数是否有传，并且是正确的顺序 下面太冲忙了，以后顺序不重要，要使用map保存起来，到时候判断就行了，个数不关心
        // 现在不用验证了
//        String param = callBackRequestData.getParam();
//        if(this.authticateParam(param)){
//            String urlParams = param.substring(param.indexOf("?")+1);
//            String[] params = urlParams.split("&");
//            String param_key = "";
//            String param_tokenId = "";
//            String param_streamId = "";
//            String key_kv = params[0];
//            String token_kv = params[1];
//            String stream_kv = params[2];
//            if(key_kv.split("=")!=null && key_kv.split("=").length>1){
//                param_key = key_kv.split("=")[1];
//            }
//            if(token_kv.split("=")!=null && token_kv.split("=").length>1){
//                param_tokenId = token_kv.split("=")[1];
//            }
//            if(stream_kv.split("=")!=null && stream_kv.split("=").length>1){
//                param_streamId = stream_kv.split("=")[1];
//            }
//            if(this.authticateOnlineUser(param_tokenId) && this.authticateKey(param_tokenId,param_streamId, param_key)){
//                // 全部验证通过后要删除本次播放的tokenId，下次播放又要重新查询赋值
//                this.deleteToken(param_tokenId);
//                flag = true;
//            }
//        }
        return flag;
    }

    /**
    *@中软华腾软件系统有限公司,未经授权不得擅自传播
    *@方法描述: 验证是否传参
    *@方法参数描述:
    ** @param param
    *@作者: 蒋正午
    *@编辑时间: 2020/04/22  12:25
    *@返回值描述: boolean
    */
    private boolean authticateParam(String  param){
        boolean flag = false;
        // 判断tcurl中的参数rtmp://192.168.117.20:1935/2001/1001?key=91D4929E1810F90B&time=1442567098/123456 只能这么传，如果流放前面我拿不到后面参数
        // 判断是否出现了参数
        if (param.contains("?")) {
            String urlParams = param.substring(param.indexOf("?")+1);
            System.err.println("测试打印====="+urlParams);
            if(StringUtils.isNotBlank(urlParams) && urlParams.split("&").length >= 3){
                flag = true;
            }else{
                logger.error("传递的参数个数不正确，不允许连接流媒体");
            }
        } else {
            logger.error("未传参数,您是非法连接用户，不允许连接流媒体");
        }
        return flag;
    }

    /**
    *@中软华腾软件系统有限公司,未经授权不得擅自传播
    *@方法描述: 验证是否为在线用户
    *@方法参数描述:
    ** @param tokenId
    *@作者: 蒋正午
    *@编辑时间: 2020/04/22  13:01
    *@返回值描述: boolean
    */
    private boolean authticateOnlineUser(String tokenId){

        if(userCache.get(tokenId)!=null){
                return true;
            }else{
                logger.error("未登录用户，不允许连接流媒体!");
                return false;
            }
    }

    /**
    *@中软华腾软件系统有限公司,未经授权不得擅自传播
    *@方法描述: 验证是否为合法加密的key
    *@方法参数描述:
    ** @param streamId
     * @param key
    *@作者: 蒋正午
    *@编辑时间: 2020/04/22  13:03
    *@返回值描述: boolean
    */
    private boolean authticateKey(String tokenId,String streamId, String key){

        // 取出tokenId与streamId然后加密最终与key比较，如果相等就通过，否则不通过
        String streamKey = Db.queryStr("SELECT streamKey FROM stream_info WHERE streamid= ? ", streamId);
        String encryStreamKey = StreamEncryUtils.encryStream(streamKey, tokenId);
        if(key.equalsIgnoreCase(encryStreamKey)){
            return true;
        }
        return false;
    }

    @Override
    public void changeONStatus(CallBackRequestData callBackRequestData) {
        if(callBackRequestData!=null){
            String key = "streamInfo_" + callBackRequestData.getStream();
            Map all = userCache.hgetAll(key);
            if(all==null || all.size()==0){
                // 说明是新建立的 以后这部分逻辑应该写在创建里面 //TODO
                Map<Object,Object> map = new HashMap<>();
                map.put("streamId", callBackRequestData.getStream());
                map.put("status", "ON");
                map.put("num",0);
                userCache.hmset(key,map);
            }else{
                userCache.hset(key,"status","ON");
            }
        }else{
            logger.error("callBack请求数据不存在");
        }

    }

    @Override
    public void chageOFFStatus(CallBackRequestData callBackRequestData) {
        if(callBackRequestData!=null){
            String key = "streamInfo_" + callBackRequestData.getStream();
            Map all = userCache.hgetAll(key);
            if(all!=null && all.size()!=0){
                userCache.hset(key,"status","OFF");
            }
        }else{
            logger.error("callBack请求数据不存在");
        }
    }

    @Override
    public void increaseOnlineNum(CallBackRequestData callBackRequestData) {
        // 先要有房间才能增加人数
        if(callBackRequestData!=null){
            String key = "streamInfo_" + callBackRequestData.getStream();
            Map all = userCache.hgetAll(key);
            if(all!=null && all.size()!=0){
                userCache.hincrBy(key, "num",1);
            }
        }else{
            logger.error("callBack请求数据不存在");
        }
    }

    @Override
    public void decreaseOnlineNum(CallBackRequestData callBackRequestData) {
        // 先要有房间才能增加人数
        if(callBackRequestData!=null){
            String key = "streamInfo_" + callBackRequestData.getStream();
            Map all = userCache.hgetAll(key);
            if(all!=null && all.size()!=0){
                if(Integer.parseInt(userCache.hget(key, "num"))>0){
                    userCache.hincrBy(key, "num",-1);
                }
            }
        }else{
            logger.error("callBack请求数据不存在");
        }
    }


    @Override
    public void deleteToken(String tokenId) {
        // 从地址里获取tokenId
        userCache.del(tokenId);
    }
}
